/**
 * Copyright (c) 2014-2016 www.nryuncang.com. All Rights Reserved.
 */
package com.topisv.tms.service.print.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.domain.WaybillApplyNewInfo;
import com.taobao.api.request.WlbWaybillIGetRequest;
import com.taobao.api.request.WlbWaybillIPrintRequest;
import com.taobao.api.response.WlbWaybillIGetResponse;
import com.taobao.api.response.WlbWaybillIPrintResponse;
import com.topisv.tms.entity.Consignor;
import com.topisv.tms.entity.CustomerAreaGroup;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.ExpressStyle;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.entity.WarehouseAddress;
import com.topisv.tms.mybatis.SqlMapDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.service.ShopSourceService;
import com.topisv.tms.service.WarehouseAddressService;
import com.topisv.tms.utils.InitProperties;
import com.topisv.tms.utils.PubUtil;
import com.topisv.tms.utils.WmsContants;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 菜鸟打印
 *
 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
 * @version 1.0.0
 */
@Component
public class CaiNiaoPrinteServiceImpl extends AbstractPrintService {
	
	private static final Logger logger = LoggerFactory.getLogger(CaiNiaoPrinteServiceImpl.class);

	
	/** 淘宝开放平台的地址--正式环境 */
	private static final String TOP_URL = InitProperties.get("top.api.url");

	private static final String APP_KEY = InitProperties.get("regAppKey");

	private static final String SECRET = InitProperties.get("regAppSecret");

	@Autowired
	private WarehouseAddressService warehouseAddressService;
	@Autowired
	private SqlMapDao sqlMapDao;
	@Autowired
	private ShopSourceService shopSourceService;
	@Autowired
	private EdiOrderDao ediOrderDao;

	@SuppressWarnings("unchecked")
    @Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public List<EdiOrder> doGetExpressNo(List<String> orderNoList, ExpressStyle template, String taskCode)
			throws Exception {

		// 第一步:基础数据
		ShopSource shopSource = shopSourceService.findByShopCode(WmsContants.SHOP_CODE_CN);
		
		// 获取仓库信息
		Map<String, WarehouseAddress> warehouseAddressMap = queryWarehouseAddress(taskCode);
		if (warehouseAddressMap == null) {
			throw new RuntimeException("找不到该商家与仓库的对应关系!");
		}
		
		List<EdiOrder> ediOrderList = sqlMapDao.selectList("ediOrderMapper.getEdiOrderListByOrdeno", orderNoList);

		// 第二步:循环订单取运单号
		TaobaoClient client = new DefaultTaobaoClient(TOP_URL, APP_KEY, SECRET);
		for (EdiOrder ediOrder : ediOrderList) {
			
			WlbWaybillIGetRequest req = new WlbWaybillIGetRequest();

			// 拼装xml
			String content = getCaiNiaoXml(ediOrder, warehouseAddressMap, shopSource, template.getLogisticsCompany().getCompanyCode());
			logger.info("{}=菜鸟取单号报文={}", ediOrder.getOrdeno(), content);
			
			// 发送菜鸟取号接口
			req.setWaybillApplyNewRequest(content);
			WlbWaybillIGetResponse wlbWaybillGetResponse = client.execute(req, shopSource.getTopisvSessionKey());
			logger.info("{}=菜鸟取单号返回的报文={}", ediOrder.getOrdeno(), wlbWaybillGetResponse);
			
			// 解析返回结果
			if (!StringUtils.isBlank(wlbWaybillGetResponse.getErrorCode())) {
				logger.error("{}=取号失败={}", ediOrder.getOrdeno(),wlbWaybillGetResponse);
				 throw new RuntimeException("取号失败:"+wlbWaybillGetResponse.getMsg()+":"+wlbWaybillGetResponse.getSubMsg());
				 
			} else {
				List<WaybillApplyNewInfo> results = wlbWaybillGetResponse.getWaybillApplyNewCols();
				
				if (results != null && !results.isEmpty()) {
					
					for (WaybillApplyNewInfo waybillApplyNewInfo : results) {
						
						String waybillNo = waybillApplyNewInfo.getWaybillCode();
//						String orderNO = waybillApplyNewInfo.getTradeOrderInfo().getPackageId();
						
						ediOrder.setToShortAddress(waybillApplyNewInfo.getShortAddress());//大头笔
						ediOrder.setMailNo(waybillNo);//运单号
						ediOrder.setCacode(template.getLogisticsCompany().getCompanyCode());//快递公司代码
						ediOrder.setCaname(template.getLogisticsCompany().getCompanyName());//快递公司名称
						ediOrder.setProductType(null);// 产品类型
						ediOrder.setPackageCenterName(waybillApplyNewInfo.getPackageCenterName());//集散地名称
						ediOrder.setPackageCenterCode(waybillApplyNewInfo.getPackageCenterCode());//集散地编码
						ediOrder.setShippingBranchName(waybillApplyNewInfo.getShippingBranchName());//发件网点名称
						ediOrder.setShippingBranchCode(waybillApplyNewInfo.getShippingBranchCode());//发件网点代码
						ediOrder.setExtSFBizType(null);//业务类型(顺丰要求)
						ediOrder.setShippingAddressCity(null);// 发件城市
						ediOrder.setPrintConfig(waybillApplyNewInfo.getPrintConfig());//打印串，需传给打印组件
					}
				}
			}
		}

		// 第三步:校验打印接口
		for (EdiOrder ediOrder : ediOrderList) {
			WlbWaybillIPrintRequest printRequest = new WlbWaybillIPrintRequest();

			// 拼装校验打印xml
			String content = getCaiNiaoPrintXml(ediOrder, warehouseAddressMap, shopSource,template.getLogisticsCompany().getCompanyCode());
			logger.info("{}=菜鸟校验打印报文={}", ediOrder.getOrdeno(), content);

			// 发送菜鸟校验打印接口
			printRequest.setWaybillApplyPrintCheckRequest(content);
			WlbWaybillIPrintResponse wlbWaybillIPrintResponse = client.execute(printRequest,shopSource.getTopisvSessionKey());
			logger.info("{}=菜鸟校验打印返回的报文={}", ediOrder.getOrdeno(), wlbWaybillIPrintResponse);
			
			// 解析返回结果
			if (!StringUtils.isBlank(wlbWaybillIPrintResponse.getErrorCode())) {
				logger.error("{}=打印校验失败={}", ediOrder.getOrdeno(), wlbWaybillIPrintResponse);
				 throw new RuntimeException("printCheck case some error:"+wlbWaybillIPrintResponse.getMsg()+":"+wlbWaybillIPrintResponse.getSubMsg());
			}
		}
		ediOrderDao.save(ediOrderList);
		return ediOrderList;
	}

	public String getCaiNiaoPrintXml(EdiOrder ediOrder, Map<String, WarehouseAddress> warehouseAddressMap,
			ShopSource shopSource, String companyCode) {

		//发货地址 
		WarehouseAddress warehouseAddress = warehouseAddressMap.get(ediOrder.getWarehouseCode());
		
		JSONObject shippingAddress = new JSONObject();
		shippingAddress.put("province", warehouseAddress.getProvName());	// 省
		shippingAddress.put("city", warehouseAddress.getCityName());	// 市
		shippingAddress.put("area", warehouseAddress.getDistName());	// 区
		shippingAddress.put("address_detail", warehouseAddress.getAddress());// 详细地址

		// 收货地址
		JSONObject consigneeAddress = new JSONObject();
		consigneeAddress.put("address_detail", ediOrder.getAddres());// 详细地址
		consigneeAddress.put("town", ediOrder.getTown());//镇
		consigneeAddress.put("area", ediOrder.getDistna());// 区
		consigneeAddress.put("city", ediOrder.getCityna());// 市
		consigneeAddress.put("province", ediOrder.getProvna());	// 省
		
		JSONObject tradeOrderInfoCol = new JSONObject();
		tradeOrderInfoCol.put("consignee_address", consigneeAddress);
		tradeOrderInfoCol.put("consignee_name", ediOrder.getRecena());//收件人
		tradeOrderInfoCol.put("consignee_phone", dealconsigneePhone(StringUtils.isEmpty(ediOrder.getMobile()) ? ediOrder.getTeleph() : ediOrder.getMobile()));//收件人电话
		tradeOrderInfoCol.put("short_address", ediOrder.getToShortAddress());//大头笔
		tradeOrderInfoCol.put("product_type", "STANDARD_EXPRESS");//产品类型
		tradeOrderInfoCol.put("real_user_id", shopSource.getTopisvUserId());// 面单使用者的用户帐号id
		tradeOrderInfoCol.put("send_name", warehouseAddressMap.get(ediOrder.getWarehouseCode()).getContact());// 发货人名称
		tradeOrderInfoCol.put("send_phone", warehouseAddressMap.get(ediOrder.getWarehouseCode()).getMobile());// 发货人电话
		tradeOrderInfoCol.put("shipping_address", shippingAddress);
		tradeOrderInfoCol.put("waybill_code", ediOrder.getMailNo());//运单号
		
		JSONArray printCheckInfoCols = new JSONArray();
		printCheckInfoCols.add(tradeOrderInfoCol);

		JSONObject json = new JSONObject();
		json.put("cp_code", companyCode);
		json.put("print_check_info_cols", printCheckInfoCols);
		return json.toString();
	}

	/**
	 * 菜鸟取单号报文
	 * 
	 *
	 * @param ediOrder
	 * @param warehouseAddressMap
	 * @param shopSource
	 * @param companyCode
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 0.0.16
	 */
	public String getCaiNiaoXml(EdiOrder ediOrder, Map<String, WarehouseAddress> warehouseAddressMap,
			ShopSource shopSource, String companyCode) {

		// 发货地址
		WarehouseAddress warehouseAddress = warehouseAddressMap.get(ediOrder.getWarehouseCode());
		JSONObject shippingAddress = new JSONObject();
		shippingAddress.put("province", warehouseAddress.getProvName());// 省
		shippingAddress.put("city", warehouseAddress.getCityName());	// 市
		shippingAddress.put("area", warehouseAddress.getDistName());	// 区
		shippingAddress.put("address_detail", warehouseAddress.getAddress());// 详细地址
		
		// 收件地址 
		JSONObject consigneeAddress = new JSONObject();
		consigneeAddress.put("address_detail", ediOrder.getAddres());	// 地址
		consigneeAddress.put("town", ediOrder.getTown());	// 街道
		consigneeAddress.put("area", ediOrder.getDistna());	// 区
		consigneeAddress.put("city", ediOrder.getCityna());// 市
		consigneeAddress.put("province", ediOrder.getProvna());// 省

		// 详细地址
		JSONObject packageItem = new JSONObject();
		packageItem.put("count", ediOrder.getSkuQty());
		packageItem.put("item_name", "商品名称");
		
		JSONArray packages = new JSONArray();
		packages.add(packageItem);

		JSONObject tradeOrderInfoCol = new JSONObject();
		tradeOrderInfoCol.put("consignee_address", consigneeAddress);// 收件地址
		tradeOrderInfoCol.put("consignee_name", ediOrder.getRecena());	// 收件人姓名
		tradeOrderInfoCol.put("consignee_phone", dealconsigneePhone(StringUtils.isEmpty(ediOrder.getMobile()) ? ediOrder.getTeleph() : ediOrder.getMobile()));//// 联系方式
		tradeOrderInfoCol.put("package_items", packages);	// 包裹信息
		tradeOrderInfoCol.put("product_type", "STANDARD_EXPRESS");	// 产品类型
		tradeOrderInfoCol.put("real_user_id", shopSource.getTopisvUserId());// 面单使用者的用户帐号id
		tradeOrderInfoCol.put("send_name", warehouseAddressMap.get(ediOrder.getWarehouseCode()).getContact());	// 发货人名称
		tradeOrderInfoCol.put("send_phone", warehouseAddressMap.get(ediOrder.getWarehouseCode()).getMobile());	// 发货人电话
		tradeOrderInfoCol.put("order_channels_type", dealChannelsType(ediOrder.getSourcePlatformCode()));	// 订单来源
		String[] orders2 = ediOrder.getOrdeno().split(";");
		Arrays.sort(orders2);
		tradeOrderInfoCol.put("trade_order_list", orders2);// 订单号
		tradeOrderInfoCol.put("package_id", ediOrder.getOrdeno());	// 包裹号

		JSONArray tradeOrderInfoCols = new JSONArray();
		tradeOrderInfoCols.add(tradeOrderInfoCol);
		
		JSONObject json = new JSONObject();
		json.put("cp_code", companyCode);
		json.put("trade_order_info_cols", tradeOrderInfoCols);
		json.put("shipping_address", shippingAddress);

		return json.toString();
	}

	/**
	 * 获取仓库信息
	 * 
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @param taskCode
	 *            任务号
	 * @return
	 */
	@SuppressWarnings("unchecked")
    private Map<String, WarehouseAddress> queryWarehouseAddress(String taskCode) {
		
		Map<String, WarehouseAddress> warehouseAddressMap = new HashMap<String, WarehouseAddress>();
		// 根据任务号查询商家仓库表的记录
		List<CustomerAreaGroup> list = PubUtil.convertListMapToObject(sqlMapDao.selectList("customerAreaGroupMapper.getCustomerAreaByTaskCode", taskCode), CustomerAreaGroup.class);
		if (list == null || list.isEmpty()) {
			return null;
		}
		
		CustomerAreaGroup customerAreaGroup = list.get(0);
		// 根据订单中仓库编码的查询仓库地址，并放到Map
		WarehouseAddress warehouseAddress = warehouseAddressService.findByWarehouseCode(customerAreaGroup.getAreaGroupCode());
		WarehouseAddress tempWarehouseAddress = new WarehouseAddress();
		BeanUtils.copyProperties(warehouseAddress, tempWarehouseAddress);
		
		// cainiaoAddressStatus等于1表示不用仓库信息，寄件人、寄件人电话使用管理发货人中的名称和电话;否则使用仓库信息
		if ("1".equals(customerAreaGroup.getCainiaoAddressStatus())) {
			List<Consignor> consignorList = PubUtil.convertListMapToObject(sqlMapDao.selectList("consignorMapper.getConsignorByCustomerCode", customerAreaGroup),Consignor.class);
			if (consignorList == null || consignorList.isEmpty()) {
				tempWarehouseAddress.setContact("");
				tempWarehouseAddress.setMobile("");
			} else {
				tempWarehouseAddress.setContact(consignorList.get(0).getName());
				tempWarehouseAddress.setMobile(consignorList.get(0).getMobile());
			}
		}
		
		warehouseAddressMap.put(warehouseAddress.getWarehouseCode(), tempWarehouseAddress);
		
		return warehouseAddressMap;
	}

	/**
	 * 订单来源字段的判断
	 * 
	 *
	 * @param orderChannelsType  订单来源
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 0.0.16
	 */
	private static String dealChannelsType(String orderChannelsType) {
		if (StringUtils.isNotBlank(orderChannelsType)) {
			if (orderChannelsType.equals("OTHER") || "NULL".equals(orderChannelsType.toUpperCase())) {
				return "OTHERS";
			} else {
				return orderChannelsType;
			}
		} else {
			return "OTHERS";
		}
	}
	
	/**
	 * 
	 * 电话字段的判断
	 *
	 * @param phone 电话
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 0.0.16
	 */
	public static String dealconsigneePhone(String phone) {
		if (!StringUtils.isBlank(phone) && phone.length() > 20) {
			return phone.substring(0, 20);
		}
		return phone;
	}

}
